package main

import (
	"fmt"
	"sync"
	"time"
)

// DataStore 包含需要保护的数据和一个读写锁
type DataStore struct {
	mu   sync.RWMutex
	data map[string]int
}

// NewDataStore 创建一个新的 DataStore
func NewDataStore() *DataStore {
	return &DataStore{
		data: make(map[string]int),
	}
}

// Get 使用读锁获取数据
func (ds *DataStore) Get(key string) (int, bool) {
	ds.mu.RLock()         // 获取读锁
	defer ds.mu.RUnlock() // 确保释放读锁
	value, exists := ds.data[key]
	return value, exists
}

// Set 使用写锁设置数据
func (ds *DataStore) Set(key string, value int) {
	ds.mu.Lock()         // 获取写锁
	defer ds.mu.Unlock() // 确保释放写锁
	ds.data[key] = value
}

func main() {
	store := NewDataStore()
	var wg sync.WaitGroup

	// 启动5个写操作goroutine
	for i := 0; i < 5; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			key := fmt.Sprintf("key%d", id%3) // 让写入集中在3个key上
			value := id * 10
			store.Set(key, value)
			fmt.Printf("写入: %s = %d\n", key, value)
			time.Sleep(time.Millisecond * 100) // 模拟写操作耗时
		}(i)
	}

	// 启动10个读操作goroutine
	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(id int) {
			defer wg.Done()
			key := fmt.Sprintf("key%d", id%3)
			value, exists := store.Get(key)
			if exists {
				fmt.Printf("读取: %s = %d\n", key, value)
			} else {
				fmt.Printf("读取: %s 不存在\n", key)
			}
			time.Sleep(time.Millisecond * 20) // 模拟读操作耗时
		}(i)
	}

	// 等待所有操作完成
	wg.Wait()
	fmt.Println("所有操作完成")
}
